#ifndef JLOG_H
#define JLOG_H

#include <QTECore/qteglobal.h>
#include <QLoggingCategory>

namespace QTE
{

#define jLogger       QTE::JMessageLogger::instance()
#define jLoggerDebug  QMessageLogger(QT_MESSAGELOG_FILE, QT_MESSAGELOG_LINE, QT_MESSAGELOG_FUNC, jLogger?jLogger->category().categoryName():"default")

#define jDebug    jLoggerDebug.debug     /* 4                                        */
#define jInfo     jLoggerDebug.info      /* 3                                        */
#define jWarning  jLoggerDebug.warning   /* 2                                        */
#define jError    jLoggerDebug.critical  /* 1 (Forcing synchronous output)           */
#define jFatal    jLoggerDebug.fatal     /* 0 (Forcing synchronous output and abort) */

class QTECORE_EXPORT JMessageLogger
{
public:
	struct Info
	{
		QString dir            = "";
		QString dirLv2         = "";
		QString category       = "default";
		qint64  maxSizeOneFile = 10240;
		qint64  maxSizeOneDay  = 10485760;
		qint64  maxSize        = 1073741824;
		int     mask           = 3;
		bool    async          = true;
		bool    noStdout       = false;
	};

public:
	enum FatalOperation
	{
		Abort, //default
		Throw,
		SysExit,
		AppExit,
		Continue,
		User
	};

public:
	explicit JMessageLogger(const Info &info, FatalOperation ope = Abort);
	JMessageLogger(const Info &info, const std::function<void(const QString&)> &customFatalOperation);
	~JMessageLogger();

public:
	static JMessageLogger *instance();

public:
	void setInfo(const Info &info);
	void setFilterQTELOG(bool filter); //Default no filtering
	void setHeaderBreaksALine(bool enable = true); //default false

public:
	virtual const QLoggingCategory &category() const;
	Info info() const;

public:
	FatalOperation fatalOperation() const;
	bool headerBreaksALine() const;

public:
	// Call before your process ends to ensure that
	// the asynchronous log is fully output.
	// (The synchronization log can be ignored)
	void exit();
};

} //namespace QTE


#endif //JLOG_H
